using Microsoft.EntityFrameworkCore;
using RealtimeCollabGame.Application.Interfaces;
using RealtimeCollabGame.Domain.Entities;
using RealtimeCollabGame.Infrastructure.Persistence;

namespace RealtimeCollabGame.Infrastructure.Repositories;

public class GameRepository : IGameRepository
{
    private readonly GameContext _context;

    public GameRepository(GameContext context)
    {
        _context = context;
    }

    public async Task<Game?> GetByIdAsync(Guid id)
    {
        return await _context.Games
            .Include(g => g.Players.OrderBy(p => p.CreatedAt))
            .Include(g => g.PaintActions)
            .Include(g => g.Canvas)
            .FirstOrDefaultAsync(g => g.Id == id);
    }

    public async Task<Game?> GetByCodeAsync(string code)
    {
        return await _context.Games
            .Include(g => g.Players.OrderBy(p => p.CreatedAt))
            .Include(g => g.PaintActions)
            .Include(g => g.Canvas)
            .FirstOrDefaultAsync(g => g.Code == code);
    }

    public async Task<IEnumerable<Game>> GetAllAsync()
    {
        return await _context.Games
            .Include(g => g.Players.OrderBy(p => p.CreatedAt))
            .Include(g => g.PaintActions)
            .Include(g => g.Canvas)
            .ToListAsync();
    }

    public async Task<Game> AddAsync(Game game)
    {
        _context.Games.Add(game);
        await _context.SaveChangesAsync();
        return game;
    }

    public async Task<Game> UpdateAsync(Game game)
    {
        _context.Games.Update(game);
        await _context.SaveChangesAsync();
        return game;
    }

    public async Task DeleteAsync(Guid id)
    {
        var game = await GetByIdAsync(id);
        if (game != null)
        {
            _context.Games.Remove(game);
            await _context.SaveChangesAsync();
        }
    }

    public async Task<bool> ExistsAsync(Guid id)
    {
        return await _context.Games.AnyAsync(g => g.Id == id);
    }

    public async Task<bool> ExistsByCodeAsync(string code)
    {
        return await _context.Games.AnyAsync(g => g.Code == code);
    }
}